package cl.nfa;

import java.util.ArrayList;
import java.util.List;

public class NFA {

    public final static char EPSILON = 0;
    
    private List<State> currentStates;
    private List<State> states;
    
    public NFA() {
        currentStates = new ArrayList<State>();
        states = new ArrayList<State>();
    }
    
    public int numStates() {
        return states.size();
    }
    
    public void merge(NFA nfa) {
        states.addAll(nfa.states);
    }
    
    public void setStartState(int node) {
        currentStates.add(states.get(node));
    }
    
    public void setTerminating(boolean value, int node) {
        states.get(node).setTerminating(value);
    }
    
    public int addState() {
        states.add(new State(false));
        
        return states.size() - 1;
    }
    
    public int addState(boolean terminating) {
        states.add(new State(terminating));
        
        return states.size() - 1;
    }
    
    public void addConnection(char value, int parent, int child) {
        states.get(parent).addConnection(value, states.get(child));
    }
    
    public boolean isMatching() {
        for(State s : currentStates) {
            if(s.isTerminating()) {
                return true;
            }
        }
        
        return false;
    }
    
    public void gobble(char value) {
        List<State> nextStates = new ArrayList<State>();
        
        for(State s: currentStates) {
            nextStates.addAll(s.getConnections(value));
        }
        
        currentStates = nextStates;
    }
    
    public String toString() {
        String result = "";
        
        for(State s : states) {
            result += s.hashCode() + "(" + s.isTerminating() + "): \n";
            result += s.toString();
        }
        
        return result;
    }
}
